using System;
using System.Collections;
using System.Collections.Generic;
using Me.Prettyprint.Hector.Api.Ddl;
using Me.Prettyprint.Cassandra.Constants;
using Org.Apache.Cassandra.Thrift;

namespace Me.Prettyprint.Cassandra.Service
{
	public class ThriftCfDef : ColumnFamilyDefinition
	{
        #region constructors
		public ThriftCfDef(CfDef d)
		{
			KeyspaceName = d.Keyspace;
			Name = d.Name;
			ColumnType = (ColumnType)System.Enum.Parse(typeof(ColumnType),d.Column_type);
			ComparatorType = ComparatorType.getByClassName(d.Comparator_type);
			SubComparatorType = ComparatorType.getByClassName(d.Subcomparator_type);
            if (d.Comparator_type.IndexOf('(') > 1)
            {
                ComparatorTypeAlias = d.Comparator_type.Substring(d.Comparator_type.IndexOf('('));
            }
            if (d.Subcomparator_type != null && d.Subcomparator_type.IndexOf('(') > 1)
            {
                SubComparatorTypeAlias = d.Subcomparator_type.Substring(d.Subcomparator_type.IndexOf('('));
            }
			Comment = d.Comment;
			RowCacheSize = d.Row_cache_size;
			RowCacheSavePeriodInSeconds = d.Row_cache_save_period_in_seconds;
			KeyCacheSize = d.Key_cache_size;
			KeyCacheSavePeriodInSeconds = d.Key_cache_save_period_in_seconds;
			KeyValidationClass = d.Key_validation_class;
			ReadRepairChance = d.Read_repair_chance;
			ColumnMetadata = ThriftColumnDef.FromThriftList(d.Column_metadata);
			GcGraceSeconds = d.Gc_grace_seconds;
			DefaultValidationClass = d.Default_validation_class;
			Id = d.Id;
			MinCompactionThreshold = d.Min_compaction_threshold == 0?CFMetaDataDefaults.DEFAULT_MIN_COMPACTION_THRESHOLD:d.Min_compaction_threshold;
			MaxCompactionThreshold = d.Max_compaction_threshold == 0?CFMetaDataDefaults.DEFAULT_MAX_COMPACTION_THRESHOLD:d.Max_compaction_threshold;
			
			ReplicateOnWrite = d.Replicate_on_write;
			
			CompactionStrategy = d.Compaction_strategy;
			CompactionStrategyOptions = d.Compaction_strategy_options;
			CompressionOptions = d.Compression_options;
			
			MergeShardsChance = d.Merge_shards_chance;
			RowCacheProvider = d.Row_cache_provider;
			KeyAlias = d.Key_alias;
			RowCacheKeysToSave = d.Row_cache_keys_to_save;
		}
		public ThriftCfDef(ColumnFamilyDefinition columnFamilyDefinition)
		{
			KeyspaceName = columnFamilyDefinition.KeyspaceName;
			Name = columnFamilyDefinition.Name;
			ColumnType = columnFamilyDefinition.ColumnType;
			ComparatorType = columnFamilyDefinition.ComparatorType;
			SubComparatorType = columnFamilyDefinition.SubComparatorType;
			ComparatorTypeAlias = columnFamilyDefinition.ComparatorTypeAlias;
			SubComparatorTypeAlias = columnFamilyDefinition.SubComparatorTypeAlias;
			Comment = columnFamilyDefinition.Comment;
			RowCacheSize = columnFamilyDefinition.RowCacheSize;
			RowCacheSavePeriodInSeconds = columnFamilyDefinition.RowCacheSavePeriodInSeconds;
			KeyCacheSize = columnFamilyDefinition.KeyCacheSize;
			KeyCacheSavePeriodInSeconds = columnFamilyDefinition.KeyCacheSavePeriodInSeconds;
			KeyValidationClass = columnFamilyDefinition.KeyValidationClass;
			KeyValidationAlias = columnFamilyDefinition.KeyValidationAlias;
			ReadRepairChance = columnFamilyDefinition.ReadRepairChance;
			ColumnMetadata = columnFamilyDefinition.ColumnMetadata;
			GcGraceSeconds = columnFamilyDefinition.GcGraceSeconds;
			DefaultValidationClass = columnFamilyDefinition.DefaultValidationClass;
			Id = columnFamilyDefinition.Id;
			MinCompactionThreshold = columnFamilyDefinition.MinCompactionThreshold == 0?CFMetaDataDefaults.DEFAULT_MIN_COMPACTION_THRESHOLD:columnFamilyDefinition.MinCompactionThreshold;
			MaxCompactionThreshold = columnFamilyDefinition.MaxCompactionThreshold == 0?CFMetaDataDefaults.DEFAULT_MAX_COMPACTION_THRESHOLD:columnFamilyDefinition.MaxCompactionThreshold;
			MemtableFlushAfterMins = columnFamilyDefinition.MemtableFlushAfterMins == 0?CFMetaDataDefaults.DEFAULT_MEMTABLE_LIFETIME_IN_MINS:columnFamilyDefinition.MemtableFlushAfterMins;
			MemtableThroughputInMb = columnFamilyDefinition.MemtableThroughputInMb == 0?CFMetaDataDefaults.DEFAULT_MEMTABLE_THROUGHPUT_IN_MB:columnFamilyDefinition.MemtableThroughputInMb;
			MemtableOperationsInMillions = columnFamilyDefinition.MemtableOperationsInMillions == 0?CFMetaDataDefaults.DEFAULT_MEMTABLE_OPERATIONS_IN_MILLIONS:columnFamilyDefinition.MemtableOperationsInMillions;
			ReplicateOnWrite = columnFamilyDefinition.ReplicateOnWrite;
			
			CompactionStrategy = columnFamilyDefinition.CompactionStrategy;
			CompactionStrategyOptions = columnFamilyDefinition.CompactionStrategyOptions;
			CompressionOptions = columnFamilyDefinition.CompressionOptions;
			
			MergeShardsChance = columnFamilyDefinition.MergeShardsChance;
			RowCacheProvider = columnFamilyDefinition.RowCacheProvider;
			KeyAlias = columnFamilyDefinition.KeyAlias;
			RowCacheKeysToSave = columnFamilyDefinition.RowCacheKeysToSave;
		}
		public ThriftCfDef(string keyspace, string columnFamilyName)
		{
			KeyspaceName = keyspace;
			Name = columnFamilyName;
			ColumnMetadata = new List<ColumnDefinition>();
			
			ColumnType = ColumnType.Standard;
			ComparatorType = ComparatorType.BYTESTYPE;
            DefaultValidationClass = ComparatorType.BYTESTYPE.ClassName;
			ReadRepairChance = CFMetaDataDefaults.DEFAULT_READ_REPAIR_CHANCE;
			KeyCacheSize = CFMetaDataDefaults.DEFAULT_KEY_CACHE_SIZE;
			KeyCacheSavePeriodInSeconds = CFMetaDataDefaults.DEFAULT_KEY_CACHE_SAVE_PERIOD_IN_SECONDS;
			GcGraceSeconds = CFMetaDataDefaults.DEFAULT_GC_GRACE_SECONDS;
			MinCompactionThreshold = CFMetaDataDefaults.DEFAULT_MIN_COMPACTION_THRESHOLD;
			MaxCompactionThreshold = CFMetaDataDefaults.DEFAULT_MAX_COMPACTION_THRESHOLD;
			MemtableFlushAfterMins = CFMetaDataDefaults.DEFAULT_MEMTABLE_LIFETIME_IN_MINS;
			MemtableThroughputInMb = CFMetaDataDefaults.DEFAULT_MEMTABLE_THROUGHPUT_IN_MB;
			MemtableOperationsInMillions = CFMetaDataDefaults.DEFAULT_MEMTABLE_OPERATIONS_IN_MILLIONS;
			ReplicateOnWrite = CFMetaDataDefaults.DEFAULT_REPLICATE_ON_WRITE;
		}
		public ThriftCfDef(string keyspace, string columnFamilyName, ComparatorType comparatorType):this(keyspace, columnFamilyName)
		{
			if (comparatorType != null)
			{
				ComparatorType = comparatorType;
			}
		}
        public ThriftCfDef(string keyspace, string columnFamilyName, ComparatorType comparatorType, List<ColumnDefinition> columnMetadata) :
            this(keyspace, columnFamilyName, comparatorType)
        {
            if (columnMetadata != null)
            {
                ColumnMetadata = columnMetadata;
            }
        }
        #endregion
		virtual public ColumnType ColumnType
		{
			get;set;
		}
		virtual public string CompactionStrategy
		{
			get;set;
		}
        virtual public Dictionary<string,string> CompactionStrategyOptions
        {
            get;set;
        }
        [System.ComponentModel.DefaultValue("")]
		public ComparatorType ComparatorType
		{
			get;set;
		}
        [System.ComponentModel.DefaultValue("")]
        virtual public string ComparatorTypeAlias
		{
			get;set;
		}
		virtual public string Comment
		{
			get;set;
		}
		public Dictionary<string,string > CompressionOptions
        {
            get;set;
        }
		public List<ColumnDefinition> ColumnMetadata
        {
            get;set;
        }
		public string DefaultValidationClass
		{
			get;set;
		}
		virtual public int GcGraceSeconds
		{
			get;set;
		}
		virtual public int Id
		{
			get;set;
		}
		virtual public byte[] KeyAlias
		{
			get;set;
		}
		virtual public double KeyCacheSize
		{
			get;set;
		}
		virtual public int KeyCacheSavePeriodInSeconds
		{
			get;set;
		}
		virtual public string KeyspaceName
		{
			get;set;
		}
		virtual public string KeyValidationClass
		{
			get;set;
		}
		virtual public string KeyValidationAlias
		{
			get;set;
		}
		virtual public int MaxCompactionThreshold
		{
			get;set;
		}
		virtual public int MinCompactionThreshold
		{
			get;set;
		}
		virtual public int MemtableFlushAfterMins
		{
			get;set;
		}
		virtual public double MemtableOperationsInMillions
		{
			get;set;
		}
		virtual public int MemtableThroughputInMb
		{
			get;set;
		}
		virtual public double MergeShardsChance
		{
			get;set;
		}
		virtual public string Name
		{
			get;set;
		}
		virtual public double RowCacheSize
		{
			get;set;
		}
		virtual public int RowCacheSavePeriodInSeconds
		{
			get;set;
		}
		virtual public double ReadRepairChance
		{
			get;set;
		}
		virtual public bool ReplicateOnWrite
		{
			get;set;
		}
		virtual public string RowCacheProvider
		{
			get;set;
		}
		virtual public int RowCacheKeysToSave
		{
			get;set;
		}
        [System.ComponentModel.DefaultValue("")]
        virtual public ComparatorType SubComparatorType
		{
			get;set;
		}
        [System.ComponentModel.DefaultValue("")]
        virtual public string SubComparatorTypeAlias
		{
			get;set;
		}
		public static List <ColumnFamilyDefinition> FromThriftList(List<CfDef> cfDefs)
        {
            if ((cfDefs == null) || cfDefs.Count == 0)
            {
                return new List<ColumnFamilyDefinition>();
            }
            List<ColumnFamilyDefinition> list = new List<ColumnFamilyDefinition>(cfDefs.Count);
            foreach (CfDef d in cfDefs)
            {
                list.Add(new ThriftCfDef(d));
            }
            return list;
        }
		public static List <CfDef> ToThriftList(List<ColumnFamilyDefinition> cfDefs)
        {
            if ((cfDefs == null) || cfDefs.Count == 0)
            {
                return new List<CfDef>();
            }
            List<CfDef> list = new List<CfDef>(cfDefs.Count);
            foreach (ColumnFamilyDefinition d in cfDefs)
            {
                list.Add(((ThriftCfDef) d).ToThrift());
            }
            return list;
        }
		public virtual CfDef ToThrift()
		{
			CfDef d = new CfDef();
            d.Keyspace = KeyspaceName;
            d.Name = Name;
			d.Column_metadata = ThriftColumnDef.ToThriftList(ColumnMetadata);
			d.Column_type = ColumnType.ToString();
			d.Comment = Comment;
			d.Comparator_type = ComparatorType.ClassName + ComparatorTypeAlias;
			d.Default_validation_class = DefaultValidationClass;
			d.Gc_grace_seconds = GcGraceSeconds;
			if (Id != 0)
            {
				d.Id = Id;
            }
			
			d.Key_cache_size = KeyCacheSize;
			d.Key_cache_save_period_in_seconds = KeyCacheSavePeriodInSeconds;
			if (false || KeyValidationClass != null)
			{
				d.Key_validation_class = KeyValidationClass + KeyValidationAlias;
			}
			else
			{
				d.Key_validation_class = KeyValidationClass;
			}
			
			d.Max_compaction_threshold = MaxCompactionThreshold;
			d.Min_compaction_threshold = MinCompactionThreshold;
			d.Read_repair_chance = ReadRepairChance;
			d.Row_cache_size = RowCacheSize;
			d.Replicate_on_write = ReplicateOnWrite;
			
			if (SubComparatorType != null)
			{
				d.Subcomparator_type = SubComparatorType.ClassName + SubComparatorTypeAlias;
			}
			
			d.Compaction_strategy = CompactionStrategy;
			d.Compaction_strategy_options = CompactionStrategyOptions;
			d.Compression_options = CompressionOptions;
			
			d.Merge_shards_chance = MergeShardsChance;
			d.Row_cache_provider = RowCacheProvider;
			d.Key_alias = KeyAlias;
			d.Row_cache_keys_to_save = RowCacheKeysToSave;
			
			return d;
		}
		public virtual void AddColumnDefinition(ColumnDefinition columnDefinition)
		{
			if (null == ColumnMetadata || ColumnMetadata.Count == 0)
			{
				ColumnMetadata = new List<ColumnDefinition>();
			}
			ColumnMetadata.Add(columnDefinition);
		}
		public override System.String ToString()
		{
            return typeof(ThriftCfDef).ToString();
		}
	}
}